﻿using System;
using Unity.Mathematics;
using UnityEngine;

namespace Jinndev {
    
    public struct Float3 : IEquatable<Float3> {

        public static readonly Float3 zero = new Float3(0);
        public static readonly Float3 one = new Float3(1);
        public static readonly Float3 half = new Float3(0.5f);

        public float x;
        public float y;
        public float z;

        public Float3(float x, float y, float z) {
            this.x = x;
            this.y = y;
            this.z = z;
        }

        public Float3(float value) {
            x = value;
            y = value;
            z = value;
        }

        public Float3(float[] array) {
            x = array.Length >= 1 ? array[0] : 0;
            y = array.Length >= 2 ? array[1] : 0;
            z = array.Length >= 3 ? array[2] : 0;
        }

        public float[] ToArray() {
            return new float[] { x, y, z };
        }

        public Float2 xy { get { return new Float2(x, y); } }

        public static implicit operator Float3(float3 v) {
            return new Float3(v.x, v.y, v.z);
        }

        public static implicit operator float3(Float3 v) {
            return new float3(v.x, v.y, v.z);
        }

        public static implicit operator Float3(Vector3 v) {
            return new Float3(v.x, v.y, v.z);
        }

        public static implicit operator Vector3(Float3 v) {
            return new Vector3(v.x, v.y, v.z);
        }

        public static bool operator ==(Float3 lhs, Float3 rhs) {
            return lhs.Equals(rhs);
        }

        public static bool operator !=(Float3 lhs, Float3 rhs) {
            return !lhs.Equals(rhs);
        }

        #region Float3 float2
        public static Float3 operator +(Float3 a, float2 b) {
            return new Float3(a.x + b.x, a.y + b.y, a.z);
        }
        public static Float3 operator +(float2 a, Float3 b) {
            return new Float3(a.x + b.x, a.y + b.y, b.z);
        }
        public static Float3 operator -(Float3 a, float2 b) {
            return new Float3(a.x - b.x, a.y - b.y, a.z);
        }
        public static Float3 operator -(float2 a, Float3 b) {
            return new Float3(a.x - b.x, a.y - b.y, b.z);
        }
        public static Float3 operator *(Float3 a, float2 b) {
            return new Float3(a.x * b.x, a.y * b.y, a.z);
        }
        public static Float3 operator *(float2 a, Float3 b) {
            return new Float3(a.x * b.x, a.y * b.y, b.z);
        }
        public static Float3 operator /(Float3 a, float2 b) {
            return new Float3(a.x / b.x, a.y / b.y, a.z);
        }
        public static Float3 operator /(float2 a, Float3 b) {
            return new Float3(a.x / b.x, a.y / b.y, b.z);
        }
        #endregion

        //#region Float3 + Float2
        //public static Float3 operator +(Float3 a, Float2 b) {
        //    return new Float3(a.x + b.x, a.y + b.y, a.z);
        //}
        //#endregion



        public bool Equals(Float3 other) {
            return other.x == x && other.y == y && other.z == z;
        }

        public override bool Equals(object obj) {
            return obj is Float3 && Equals((Float3)obj);
        }

        public override int GetHashCode() {
            return (int)math.hash(new float3(x, y, z));
        }

        public override string ToString() {
            return $"Float3({x}, {y}, {z})";
        }

    }

}
